﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Forms;
using FxSuperCore.Log;
using FxSuperCore.Utils;
using FxWinSuper.Annotations;
using FxWinSuper.Functions;
using FxWinSuper.Plugin;
using FxWinSuper.Plugin.Data;
using FxWinSuper.Plugin.Extension;
using FxWinSuper.Util;
using Timer = System.Threading.Timer;

namespace FxWinSuper.UI.Menu.Pages
{
	internal class PluginPageViewModel : INotifyPropertyChanged
	{
		public static PluginPageViewModel Instance { get; private set; }
		public static BoolToStringConverter LoadStatusConverter => new BoolToStringConverter("已加载", "未加载");
		public static BoolToStringConverter DisableStatusStatusConverter => new BoolToStringConverter("禁用", "启用");
		public static CommPropConvert NullObjectToVisibleConvert => new CommPropConvert(obj => obj == null ? Visibility.Collapsed : Visibility.Visible);
		public static CommPropConvert DisableBtnTextConvert => new CommPropConvert(obj => (bool)obj ? "启用插件" : "禁用插件");

		private static ILogPrint Logger = InternalLog.Instance;
		// 检测更新时间间隔
		private static readonly int UpdateDetectTimerMill = 5 * 60 * 1000;
		// 检测更新定时器
		private readonly Timer updateTimer;
		// 插件更新通知表
		private HashSet<string> _updatedPluginNames = new HashSet<string>();
		// 是否提示过插件更新异常
		private volatile bool _isTipPluginUpdateException = false;

		static PluginPageViewModel()
		{
			Instance = new PluginPageViewModel();
		}

		private PluginPageViewModel()
		{
			PluginController.PluginStatueChanged += PluginController_PluginStatueChanged;
			PluginController.PluginUninstalled += PluginController_PluginUninstalled;
			updateTimer = new Timer(PluginUpdateDetect, null, 0, UpdateDetectTimerMill);
		}

		private IPluginStore _pluginStore;

		public IPluginStore PluginStore
		{
			get => _pluginStore;
			set
			{
				if (value != null)
				{
					_pluginStore = value;
					HasPluginStore = true;
				}
			}
		}

		public bool HasPluginStore
		{
			get => _pluginStore != null;
			set => OnPropertyChanged();
		}

		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// 本地插件实体
		/// </summary>
		public ObservableCollection<LocalPluginEntity> LocalPluginEntities { get; set; } = new ObservableCollection<LocalPluginEntity>();

		/// <summary>
		/// 远程插件实体
		/// </summary>
		public ObservableCollection<RemotePluginEntity> RemotePluginEntities { get; set; } = new ObservableCollection<RemotePluginEntity>();

		[NotifyPropertyChangedInvocator]
		protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
		}

		/// <summary>
		/// 本地插件状态改变事件
		/// </summary>
		private void PluginController_PluginStatueChanged(LocalPluginEntity plugin)
		{
			for (var i = 0; i < LocalPluginEntities.Count; i++)
			{
				if (LocalPluginEntities[i].PluginName == plugin.PluginName)
				{
					LocalPluginEntities.RemoveAt(i);
					LocalPluginEntities.Insert(i, plugin);
					return;
				}
			}
			LocalPluginEntities.Add(plugin);
		}

		/// <summary>
		/// 插件卸载回调
		/// </summary>
		private void PluginController_PluginUninstalled(LocalPluginEntity plugin)
		{
			for (var i = 0; i < LocalPluginEntities.Count; i++)
			{
				if (LocalPluginEntities[i].PluginName == plugin.PluginName)
				{
					LocalPluginEntities.RemoveAt(i);
					return;
				}
			}
		}


		/// <summary>
		/// 插件更新检测
		/// </summary>
		private async void PluginUpdateDetect(object _)
		{
			Logger.Debug("开始检测插件更新");
			if (!HasPluginStore)
			{
				Logger.Debug("未安装插件更新检测服务，中止更新检测");
				return;
			}
			List<LocalPluginEntity> localPluginEntities = PluginController.GetLocalPlugins();
			foreach (LocalPluginEntity localPluginEntity in localPluginEntities)
			{
				try
				{
					RemotePluginEntity remotePluginInfo = await PluginStore.GetPluginInfo(localPluginEntity.PluginName);
					if (remotePluginInfo == null)
					{
						Logger.Debug($"未在插件商店检索到插件:[{localPluginEntity.PluginName}]相关信息");
						continue;
					}

					if (remotePluginInfo.VersionCode > localPluginEntity.VersionCode)
					{
						if (_updatedPluginNames.Contains(localPluginEntity.PluginName))
						{
							continue;
						}

						_updatedPluginNames.Add(localPluginEntity.PluginName);
						Logger.Info($"插件:[{localPluginEntity.PluginName}]当前版本[{localPluginEntity.Version}][{localPluginEntity.VersionCode}]，最新版本[{remotePluginInfo.Version}][{remotePluginInfo.VersionCode}]");
						CommonUtils.ShowWinToast("提示", $"插件[{localPluginEntity.PluginName}]有新的可用更新", ToolTipIcon.Info);
					}
				}
				catch (Exception e)
				{
					Logger.Error($"插件更新服务异常:{e.Message}, stack:{e.StackTrace}");
					if (!_isTipPluginUpdateException)
					{
						CommonUtils.ShowWinToast("提示", "检测插件更新失败");
						_isTipPluginUpdateException = true;
					}
				}
			}
		}

	}
}
